package com.tencent.wxcloudrun.service.business.zuke;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tencent.wxcloudrun.config.CustomException;
import com.tencent.wxcloudrun.config.UserContext;
import com.tencent.wxcloudrun.pojo.dto.resp.GetBillDetailResp;
import com.tencent.wxcloudrun.pojo.dto.resp.GetBillListResp;
import com.tencent.wxcloudrun.pojo.dto.resp.GetSumBillResp;
import com.tencent.wxcloudrun.pojo.po.XFeeManageMaster;
import com.tencent.wxcloudrun.pojo.po.XFeeManageSon;
import com.tencent.wxcloudrun.pojo.po.XHouseInfo;
import com.tencent.wxcloudrun.service.XFeeManageMasterService;
import com.tencent.wxcloudrun.service.XFeeManageSonService;
import com.tencent.wxcloudrun.service.XHouseInfoService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class BillSeeService {

    @Resource
    private XFeeManageMasterService xFeeManageMasterService;

    @Resource
    private XFeeManageSonService xFeeManageSonService;

    @Resource
    private XHouseInfoService xHouseInfoService;

    public List<GetBillListResp> getBillList() {
        String openId = UserContext.getOpenId();
        List<GetBillListResp> respList = new ArrayList<>();
        LambdaQueryWrapper<XFeeManageMaster> xFeeManageMasterLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xFeeManageMasterLambdaQueryWrapper.eq(XFeeManageMaster::getTenantId, openId);
        List<XFeeManageMaster> xFeeManageMasters = xFeeManageMasterService.list(xFeeManageMasterLambdaQueryWrapper);
        if (CollUtil.isEmpty(xFeeManageMasters)) {
            return respList;
        }
        List<String> feeList = xFeeManageMasters.stream().map(XFeeManageMaster::getBusinessId).collect(Collectors.toList());
        LambdaQueryWrapper<XFeeManageSon> xFeeManageSonLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xFeeManageSonLambdaQueryWrapper.in(XFeeManageSon::getMasterId, feeList);
        xFeeManageSonLambdaQueryWrapper.orderByDesc(XFeeManageSon::getCreateTime);
        List<XFeeManageSon> xFeeManageSons = xFeeManageSonService.list(xFeeManageSonLambdaQueryWrapper);
        List<String> houseList = xFeeManageMasters.stream().map(XFeeManageMaster::getHouseId).distinct().collect(Collectors.toList());
        LambdaQueryWrapper<XHouseInfo> xHouseInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xHouseInfoLambdaQueryWrapper.in(XHouseInfo::getHouseId, houseList);
        List<XHouseInfo> xHouseInfos = xHouseInfoService.list(xHouseInfoLambdaQueryWrapper);
        for (XFeeManageSon xFeeManageSon : xFeeManageSons) {
            GetBillListResp getBillListResp = new GetBillListResp();
            getBillListResp.setBillId(xFeeManageSon.getFeeId());
            XFeeManageMaster xFeeManageMaster = xFeeManageMasters.stream().filter(var -> var.getBusinessId().equals(xFeeManageSon.getMasterId())).collect(Collectors.toList()).get(0);
            XHouseInfo houseInfo = xHouseInfos.stream().filter(var -> var.getHouseId().equals(xFeeManageMaster.getHouseId())).collect(Collectors.toList()).get(0);
            getBillListResp.setHouseName(houseInfo.getHouseName());
            getBillListResp.setFeeDate(DateUtil.format(xFeeManageSon.getCreateTime(), "yyyy-MM-dd"));
            BigDecimal water = NumberUtil.mul(xFeeManageSon.getWaterDiff(), xFeeManageSon.getWaterUnit());
            BigDecimal power = NumberUtil.mul(xFeeManageSon.getPowerDiff(), xFeeManageSon.getPowerUnit());
            BigDecimal gas = NumberUtil.mul(xFeeManageSon.getGasDiff(), xFeeManageSon.getGasUnit());
            BigDecimal add = NumberUtil.add(water, power, gas, xFeeManageSon.getManageFee(), xFeeManageSon.getMouthFee(), xFeeManageSon.getDeposit());
            getBillListResp.setSumFee("共" + add.toPlainString() + "元");
            respList.add(getBillListResp);
        }
        return respList;
    }

    public GetBillDetailResp getBillDetail(String billId) {
        LambdaQueryWrapper<XFeeManageSon> xFeeManageSonLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xFeeManageSonLambdaQueryWrapper.in(XFeeManageSon::getFeeId, billId);
        XFeeManageSon xFeeManageSon = xFeeManageSonService.getOne(xFeeManageSonLambdaQueryWrapper);
        GetBillDetailResp getBillDetailResp = new GetBillDetailResp();
        getBillDetailResp.setMonthRent(xFeeManageSon.getMouthFee().toPlainString());
        getBillDetailResp.setManageFee(xFeeManageSon.getManageFee().toPlainString());
        getBillDetailResp.setDeposit(xFeeManageSon.getDeposit().toPlainString());
        BigDecimal water = NumberUtil.mul(xFeeManageSon.getWaterDiff(), xFeeManageSon.getWaterUnit());
        BigDecimal power = NumberUtil.mul(xFeeManageSon.getPowerDiff(), xFeeManageSon.getPowerUnit());
        BigDecimal gas = NumberUtil.mul(xFeeManageSon.getGasDiff(), xFeeManageSon.getGasUnit());
        BigDecimal add = NumberUtil.add(water, power, gas, xFeeManageSon.getManageFee(), xFeeManageSon.getMouthFee(), xFeeManageSon.getDeposit());
        getBillDetailResp.setWaterFee(water.toPlainString());
        getBillDetailResp.setElectricFee(power.toPlainString());
        getBillDetailResp.setGasFee(gas.toPlainString());
        getBillDetailResp.setTotalFee(add.toPlainString());
        getBillDetailResp.setPayType("线下");
        getBillDetailResp.setPayTime(DateUtil.format(xFeeManageSon.getCreateTime(), DatePattern.NORM_DATETIME_PATTERN));
        LambdaQueryWrapper<XFeeManageMaster> xFeeManageMasterLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xFeeManageMasterLambdaQueryWrapper.eq(XFeeManageMaster::getBusinessId, xFeeManageSon.getMasterId());
        XFeeManageMaster xFeeManageMaster = xFeeManageMasterService.getOne(xFeeManageMasterLambdaQueryWrapper);
        getBillDetailResp.setRentStatus("租住中".equals(xFeeManageMaster.getCurStatus()) ? "租住中" : "已退租");
        return getBillDetailResp;
    }

    public GetSumBillResp getSumBill(List<String> billIds) {
        if (CollUtil.isEmpty(billIds)) {
            throw new CustomException("请先勾选账单！");
        }
        LambdaQueryWrapper<XFeeManageSon> xFeeManageSonLambdaQueryWrapper = new LambdaQueryWrapper<>();
        xFeeManageSonLambdaQueryWrapper.in(XFeeManageSon::getFeeId, billIds);
        List<XFeeManageSon> xFeeManageSon = xFeeManageSonService.list(xFeeManageSonLambdaQueryWrapper);
        GetSumBillResp getSumBillResp = new GetSumBillResp();
        getSumBillResp.setPeriod(String.valueOf(billIds.size()));
        getSumBillResp.setZuJinSum(NumberUtil.add(xFeeManageSon.stream().map(XFeeManageSon::getMouthFee).toArray(BigDecimal[]::new)).toPlainString());
        getSumBillResp.setManageSum(NumberUtil.add(xFeeManageSon.stream().map(XFeeManageSon::getManageFee).toArray(BigDecimal[]::new)).toPlainString());
        getSumBillResp.setDepositSum(NumberUtil.add(xFeeManageSon.stream().map(XFeeManageSon::getDeposit).toArray(BigDecimal[]::new)).toPlainString());
        getSumBillResp.setWaterUseSum(NumberUtil.add(xFeeManageSon.stream().map(XFeeManageSon::getWaterDiff).toArray(BigDecimal[]::new)).toPlainString());
        getSumBillResp.setElectricUseSum(NumberUtil.add(xFeeManageSon.stream().map(XFeeManageSon::getPowerDiff).toArray(BigDecimal[]::new)).toPlainString());
        // 计算水费总和：waterDiff * waterUnit
        getSumBillResp.setWaterSum(NumberUtil.add(xFeeManageSon.stream().map(son -> NumberUtil.mul(son.getWaterDiff(), son.getWaterUnit()))
                .toArray(BigDecimal[]::new)).toPlainString());
        // 计算电费总和：powerDiff * powerUnit
        getSumBillResp.setElectricSum(NumberUtil.add(xFeeManageSon.stream().map(son -> NumberUtil.mul(son.getPowerDiff(), son.getPowerUnit())) // 自动处理null
                .toArray(BigDecimal[]::new)).toPlainString());
        // 计算燃气费总和：gasDiff * gasUnit
        getSumBillResp.setGasSum(NumberUtil.add(xFeeManageSon.stream().map(son -> NumberUtil.mul(son.getGasDiff(), son.getGasUnit())) // 自动处理null
                .toArray(BigDecimal[]::new)).toPlainString());
        getSumBillResp.setGasUseSum(NumberUtil.add(xFeeManageSon.stream().map(XFeeManageSon::getGasDiff).toArray(BigDecimal[]::new)).toPlainString());
        return getSumBillResp;
    }
}
